package com.adou.Controller;

import com.adou.common.controller.BaseController;
import com.adou.common.dto.AddFieldDto;
import com.adou.common.dto.FormDataInDto;
import com.adou.common.model.FlowMain;
import com.adou.common.model.FlowMainFile;
import com.adou.common.model.WorkAttach;
import com.adou.common.util.Const;
import com.adou.common.util.StringUtil;
import com.adou.service.FlowMainFileService;
import com.adou.service.FormModelService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("flowMainFile")
@Scope(value = "prototype")
public class FlowMainFileController extends BaseController {

    @Autowired
    private FlowMainFileService flowMainFileService;

    @Autowired
    private FormModelService formModelService;

    /**
     * 流程实例分页列表
     *
     * @param pageNum
     * @param pageSize
     * @param m        find 模糊查询内容：流程名称、当前节点名称、标题、办理人
     *                 p p=0 待办 p=1 在办 p=2 已办 p=3 流程监控
     * @return
     */
    @GetMapping("pageList")
    private Map<String, Object> pageList(int pageNum, int pageSize, @RequestParam Map<String, Object> m) {
        if (StringUtil.isBlank(m.get("p"))) {
            error(103, "p为空");
            return resultMap;
        }
        if (!StringUtil.isNumeric(m.get("p").toString())) {
            error(104, "p只能为整数");
            return resultMap;
        }
        int p = Integer.parseInt(m.get("p").toString());
        if (p < 0 || p > 4) {
            error(105, "p只能是0,1,2,3,4");
            return resultMap;
        }
        try {
            Map<String, Object> map = flowMainFileService.pageList(pageNum, pageSize, m);
            if ((long) map.get("totalcount") > 0) {
                resultMap.put("data", map);
                resultMap.put("msg", Const.DATA_SUCCEED);
            } else {
                error(101, "数据为空");
            }
        } catch (Exception e) {
            error(Const.DATA_ERROR_112, Const.DATA_FAIL);
            logger.error(e.toString());
        }
        return resultMap;
    }

    /**
     * 添加流程实例
     *
     * @param map ifmid 流程主键 ctitle 标题 ccreator 用户
     *            uid 用户主键
     * @return
     */
    @PostMapping("insert")
    private Map<String, Object> insert(@RequestBody Map<String, Object> map) {
        try {
            resultMap.putAll(flowMainFileService.insertSelective(map));
        } catch (Exception e) {
            logger.error(e.toString(), e);
            error(Const.ADD_ERROR_202, Const.SAVE_FAIL);
        }
        return resultMap;
    }

    /**
     * 删除流程实例
     *
     * @param id
     * @return
     */
    @PostMapping("delete")
    private Map<String, Object> delete(Long id) {
        try {
            FlowMainFile flowMainFile = new FlowMainFile();
            flowMainFile.setId(id);
            int res = flowMainFileService.delete(flowMainFile);
            if (res == 0) {
                error(Const.DEL_ERROR_301, Const.DEL_FAIL);
            } else if (res == -1) {
                error(303, "流程不存在，无法删除");
            } else if (res == -2) {
                error(304, "流程已办结，无法删除");
            } else if (res == -3) {
                error(305, "流程已签收，无法删除");
            } else if (res == -4) {
                error(306, "流程定义表数据不存在");
            } else if (res == -5) {
                error(307, "当前用户无删除权限");
            } else if (res == -6) {
                error(308, "非初始阶段，无权删除");
            } else {
                resultMap.put("msg", Const.DEL_SUCCEED);
                resultMap.put("data", res);
            }
        } catch (Exception e) {
            logger.error(e.toString(), e);
            error(Const.DEL_ERROR_302, Const.DEL_FAIL);
        }
        return resultMap;
    }

    /**
     * 根据用户主键查询流程列表
     *
     * @return
     */
    @PostMapping("queryFlowListById")
    private Map<String, Object> queryFlowListById() {
        try {
            List<FlowMain> list = flowMainFileService.queryFlowListById();
            if (list.size() > 0) {
                resultMap.put("data", list);
                resultMap.put("msg", Const.DATA_SUCCEED);
            } else {
                error(Const.LIST_ERROR_101, Const.DATA_FAIL);
            }
        } catch (Exception e) {
            logger.error(e.toString(), e);
            error(Const.LIST_ERROR_102, Const.DATA_FAIL);
        }
        return resultMap;
    }

    /**
     * 根据ifmid 获取表单html数据
     *
     * @param ifmid 流程定义表主键
     * @return
     */
    @GetMapping("getFormDataByIfmid")
    private Map<String, Object> getFormDataByIfmid(Long ifmid) {
        if (ifmid == null || ifmid == 0) {
            error(103, "ifmid为空");
            return resultMap;
        }
        try {
            Map<String, Object> m = flowMainFileService.getFormDataByIfmid(ifmid);
            if (!m.isEmpty()) {
                resultMap.put("data", m);
                resultMap.put("msg", Const.DATA_SUCCEED);
            } else {
                error(104, "未查询到相关数据");
            }
        } catch (Exception e) {
            logger.error(e.toString(), e);
            error(Const.LIST_ERROR_102, Const.DATA_FAIL);
        }
        return resultMap;
    }

    /**
     * 根据流程办理主表主键获取表单详细数据
     *
     * @param id
     * @return
     */
    @GetMapping("getFormDataById")
    private Map<String, Object> getFormDataById(Long id) {
        if (id == null || id == 0) {
            error(103, "id为空");
            return resultMap;
        }
        try {
            Map<String, Object> m = flowMainFileService.getFormDataById(id);
            resultMap.putAll(m);
        } catch (Exception e) {
            logger.error(e.toString(), e);
            error(Const.LIST_ERROR_102, Const.DATA_FAIL);
        }
        return resultMap;
    }

    /**
     * 填写表单
     *
     * @param map id 流程办理主表主键 ccurtid 当前流程节点主键
     *            ifmid 流程定义表主键
     * @return
     */
    @PostMapping("fillForm")
    public Map<String, Object> fillForm(@RequestBody Map<String, Object> map) {
        if (StringUtil.isBlank(map.get("id"))) {
            error(204, "id为空");
            return resultMap;
        }
        if (StringUtil.isBlank(map.get("ccurtid"))) {
            error(205, "ccurtid为空");
            return resultMap;
        }
        if (StringUtil.isBlank(map.get("ifmid"))) {
            error(206, "ifmid为空");
            return resultMap;
        }

        //表单数据整合
        FormDataInDto formDataInDto = new FormDataInDto();
        Map<String, Object> map1 = (Map<String, Object>) map.get("dataObj");
        if (StringUtil.isBlank(map1.get("flowId"))) {
            error(207, "流程主键不存在");
            return resultMap;
        }
        if (StringUtil.isBlank(map1.get("formId"))) {
            error(208, "表单主键不存在");
            return resultMap;
        }
        formDataInDto.setFormId(Long.parseLong(map1.get("formId").toString()));
        formDataInDto.setFlowId(Long.parseLong(map1.get("flowId").toString()));
        if (StringUtil.isBlank(map1.get("id"))) {
            formDataInDto.setId(null);
        } else {
            formDataInDto.setId(Long.parseLong(map1.get("id").toString()));
        }
        List<AddFieldDto> addFieldDtoList = new LinkedList<>();
        ObjectMapper mapper = new ObjectMapper();
        for (Map<String, Object> map2 : (List<Map<String, Object>>) map.get("addList")) {
            AddFieldDto addFieldDto = mapper.convertValue(map2, AddFieldDto.class);
            addFieldDtoList.add(addFieldDto);
        }
        formDataInDto.setAddList(addFieldDtoList);

        try {
            Map<String, Object> m = flowMainFileService.fillForm(map);
            int result = (int) m.get("result");
            if (result == 1) {
                int res = formModelService.setFormContentByFlowId(formDataInDto.getAddList(), formDataInDto.getFlowId(),
                        formDataInDto.getFormId(), formDataInDto.getId());
                if (res != 1) {
                    resultMap.put("result", Const.ADD_ERROR_201);
                    resultMap.put("msg", Const.SAVE_FAIL);
                }
            } else {
                if (result == 7) {
                    resultMap.put("result", 1);
                    resultMap.put("msg", m.get("msg"));
                } else {
                    resultMap.putAll(m);
                }
            }
        } catch (Exception e) {
            logger.error(e.toString(), e);
            error(202, Const.DATA_FAIL);
        }
        return resultMap;
    }

    /**
     * 表单重新提交
     *
     * @param map id 流程办理主表主键 ccurtid 当前流程节点主键
     *            ifmid 流程定义表主键 ctodoids 办理人id ctodousers 办理人姓名
     * @return
     */
    @PostMapping("reFill")
    public Map<String, Object> reFill(@RequestBody Map<String, Object> map) {
        if (StringUtil.isBlank(map.get("id"))) {
            error(204, "id为空");
            return resultMap;
        }
        if (StringUtil.isBlank(map.get("ccurtid"))) {
            error(205, "ccurtid为空");
            return resultMap;
        }
        if (StringUtil.isBlank(map.get("ifmid"))) {
            error(206, "ifmid为空");
            return resultMap;
        }

        //表单数据整合
        FormDataInDto formDataInDto = new FormDataInDto();
        Map<String, Object> map1 = (Map<String, Object>) map.get("dataObj");
        if (StringUtil.isBlank(map1.get("flowId"))) {
            error(207, "流程主键不存在");
            return resultMap;
        }
        if (StringUtil.isBlank(map1.get("formId"))) {
            error(208, "表单主键不存在");
            return resultMap;
        }
        formDataInDto.setFormId(Long.parseLong(map1.get("formId").toString()));
        formDataInDto.setFlowId(Long.parseLong(map1.get("flowId").toString()));
        if (StringUtil.isBlank(map1.get("id"))) {
            formDataInDto.setId(null);
        } else {
            formDataInDto.setId(Long.parseLong(map1.get("id").toString()));
        }
        List<AddFieldDto> addFieldDtoList = new LinkedList<>();
        ObjectMapper mapper = new ObjectMapper();
        for (Map<String, Object> map2 : (List<Map<String, Object>>) map.get("addList")) {
            AddFieldDto addFieldDto = mapper.convertValue(map2, AddFieldDto.class);
            addFieldDtoList.add(addFieldDto);
        }
        formDataInDto.setAddList(addFieldDtoList);

        try {
            Map<String, Object> m = flowMainFileService.reFill(map);
            int result = (int) m.get("result");
            if (result == 1) {
                int res = formModelService.setFormContentByFlowId(formDataInDto.getAddList(), formDataInDto.getFlowId(),
                        formDataInDto.getFormId(), formDataInDto.getId());
                if (res != 1) {
                    resultMap.put("result", Const.ADD_ERROR_201);
                    resultMap.put("msg", Const.SAVE_FAIL);
                }
            } else {
                if (result == 7) {
                    resultMap.put("result", 1);
                    resultMap.put("msg", m.get("msg"));
                } else {
                    resultMap.putAll(m);
                }
            }
        } catch (Exception e) {
            logger.error(e.toString(), e);
            error(202, Const.DATA_FAIL);
        }
        return resultMap;
    }

    /**
     * 签收
     *
     * @param id 流程办理主表主键
     * @return
     */
    @PostMapping("signFlow")
    private Map<String, Object> signFlow(Long id) {
        try {
            resultMap.putAll(flowMainFileService.signFlow(id));
        } catch (Exception e) {
            logger.error(e.toString(), e);
            error(102, Const.DATA_FAIL);
        }
        return resultMap;
    }

    /**
     * 撤销流程
     *
     * @param id 流程办理主表主键
     * @return
     */
    @PostMapping("backFlow")
    private Map<String, Object> backFlow(Long id) {
        try {
            resultMap.putAll(flowMainFileService.backFlow(id));
        } catch (Exception e) {
            logger.error(e.toString(), e);
            error(102, Const.DATA_FAIL);
        }
        return resultMap;
    }

    /**
     * 退回流程
     *
     * @param id   流程办理主表主键
     * @param note 退回意见
     * @return
     */
    @PostMapping("returnFlow")
    private Map<String, Object> returnFlow(Long id, String note) {
        try {
            resultMap.putAll(flowMainFileService.returnFlow(id, note));
        } catch (Exception e) {
            logger.error(e.toString(), e);
            error(102, Const.DATA_FAIL);
        }
        return resultMap;
    }

    /**
     * 查询表单数据
     *
     * @param id 流程办理主表主键
     * @return
     */
    @GetMapping("queryDetailById")
    private Map<String, Object> queryDetailById(Long id) {
        try {
            resultMap.putAll(flowMainFileService.queryDetailById(id));
        } catch (Exception e) {
            logger.error(e.toString(), e);
            error(102, Const.DATA_FAIL);
        }
        return resultMap;
    }

    /**
     * 特送节点
     *
     * @param map id 流程办理主表主键
     *            ctodoids 待办理人主键 ctodousers 待办理人姓名（","隔开）
     *            ccurtid 节点主键
     * @return
     */
    @PostMapping("pushTask")
    private Map<String, Object> pushTask(@RequestBody Map<String, Object> map) {
        try {
            resultMap.putAll(flowMainFileService.pushTask(map));
        } catch (Exception e) {
            logger.error(e.toString(), e);
            error(302, Const.SAVE_FAIL);
        }
        return resultMap;
    }

    /**
     * 特送个人
     *
     * @param map id 流程办理主表主键
     *            todoids 待办理人主键 todousers 待办理人姓名（","隔开）
     * @return
     */
    @PostMapping("pushPerson")
    private Map<String, Object> pushPerson(@RequestBody Map<String, Object> map) {
        try {
            resultMap.putAll(flowMainFileService.pushPerson(map));
        } catch (Exception e) {
            logger.error(e.toString(), e);
            error(302, Const.SAVE_FAIL);
        }
        return resultMap;
    }

    /**
     * 催办流程
     *
     * @param id 流程办理表主键
     * @return
     */
    @GetMapping("urgeFlow")
    private Map<String, Object> urgeFlow(Long id) {
        try {
            resultMap.putAll(flowMainFileService.urgeFlow(id));
        } catch (Exception e) {
            logger.error(e.toString(), e);
            error(302, "催办失败");
        }
        return resultMap;
    }

    /**
     * 上传图片
     *
     * @param fileList   可以多图片上传
     * @param workAttach iflid 流程办理主id
     *                   itaskid 所属环节id ctaskname 所属环节
     *                   cident 异步标识（这些参数必传）
     * @return
     */
    @PostMapping("uploadPicAsync")
    private Map<String, Object> uploadPicAsync(List<MultipartFile> fileList, WorkAttach workAttach) {
        try {
            resultMap.putAll(flowMainFileService.uploadFileAsync(fileList, workAttach, "pic"));
        } catch (Exception e) {
            logger.error(e.toString(), e);
            error(202, "上传失败");
        }
        return resultMap;
    }

    /**
     * 上传文件
     *
     * @param fileList   可以多文件上传
     * @param workAttach iflid 流程办理主id
     *                   itaskid 所属环节id ctaskname 所属环节
     *                   cident 异步标识（这些参数必传）
     * @return
     */
    @PostMapping("uploadFileAsync")
    private Map<String, Object> uploadFileAsync(@RequestParam("fileList") List<MultipartFile> fileList, WorkAttach workAttach) {
        try {
            resultMap.putAll(flowMainFileService.uploadFileAsync(fileList, workAttach, "file"));
        } catch (Exception e) {
            logger.error(e.toString(), e);
            error(202, "上传失败");
        }
        return resultMap;
    }

    /**
     * 删除当前环节附件
     *
     * @param id 附件主键
     * @return
     */
    @GetMapping("deleteFile")
    private Map<String, Object> deleteFile(Long id) {
        try {
            resultMap.putAll(flowMainFileService.deleteFile(id));
        } catch (Exception e) {
            logger.error(e.toString(), e);
            error(402, "删除失败");
        }
        return resultMap;
    }

}
